﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
namespace PrisonStep
{
    /// <summary>
    /// This class implements one section of our prison ship
    /// </summary>
    public class MouseTrack
    {
        #region Fields



        /// <summary>
        /// The game we are associated with
        /// </summary>
        private PrisonGame game;

        private Dictionary<string, List<Vector2>> regions = new Dictionary<string, List<Vector2>>();
        private string region;
        public string Region { get { return region; } }

        private PSLineDraw lineDraw;
        public PSLineDraw LineDraw { get { return lineDraw; } }
        private MouseState lastMouseState;
        private float bufferX = 0;
        private float bufferY = 0;
        private Vector3 crosshairCoordinate = new Vector3(0, 0, 0);
        #endregion

        #region Construction and Loading

        /// <summary>
        /// Constructor. Creates an object for a section.
        /// </summary>
        /// <param name="game"></param>
        /// <param name="section"></param>
        public MouseTrack(PrisonGame game)
        {
            this.game = game;

            // this.asset = asset;
        }


        private string TestRegion(Vector3 v3)
        {
            // Convert to a 2D Point
            float x = v3.X;
            float y = v3.Z;

            foreach (KeyValuePair<string, List<Vector2>> region in regions)
            {
                // For now we ignore the walls
                if (region.Key.StartsWith("W"))
                    continue;

                for (int i = 0; i < region.Value.Count; i += 3)
                {
                    float x1 = region.Value[i].X;
                    float x2 = region.Value[i + 1].X;
                    float x3 = region.Value[i + 2].X;
                    float y1 = region.Value[i].Y;
                    float y2 = region.Value[i + 1].Y;
                    float y3 = region.Value[i + 2].Y;

                    float d = 1.0f / ((x1 - x3) * (y2 - y3) - (x2 - x3) * (y1 - y3));
                    float l1 = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) * d;
                    if (l1 < 0)
                        continue;

                    float l2 = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) * d;
                    if (l2 < 0)
                        continue;

                    float l3 = 1 - l1 - l2;
                    if (l3 < 0)
                        continue;

                    return region.Key;
                }
            }

            return "";
        }


        /// <summary>
        /// This function is called to load content into this component
        /// of our game.
        /// </summary>
        /// <param name="content">The content manager to load from.</param>
        public void LoadContent(ContentManager content)
        {
            ///////////////////////////////////////////////
            ////////// stuff for collision //////////////
            ///////////////////////////////////////////////

            Model model2 = content.Load<Model>("AntonPhibesCollision");
            Matrix[] M = new Matrix[model2.Bones.Count];
            model2.CopyAbsoluteBoneTransformsTo(M);

            foreach (ModelMesh mesh in model2.Meshes)
            {
                // For accumulating the triangles for this mesh
                List<Vector2> triangles = new List<Vector2>();

                // Loop over the mesh parts
                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                {
                    // 
                    // Obtain the vertices for the mesh part
                    //

                    int numVertices = meshPart.VertexBuffer.VertexCount;
                    VertexPositionColorTexture[] verticesRaw = new VertexPositionColorTexture[numVertices];
                    meshPart.VertexBuffer.GetData<VertexPositionColorTexture>(verticesRaw);

                    //
                    // Obtain the indices for the mesh part
                    //

                    int numIndices = meshPart.IndexBuffer.IndexCount;
                    short[] indices = new short[numIndices];
                    meshPart.IndexBuffer.GetData<short>(indices);
                    //
                    // Build the list of triangles
                    //

                    for (int i = 0; i < meshPart.PrimitiveCount * 3; i++)
                    {
                        // The actual index is relative to a supplied start position
                        int index = i + meshPart.StartIndex;

                        // Transform the vertex into world coordinates
                        Vector3 v = Vector3.Transform(verticesRaw[indices[index] + meshPart.VertexOffset].Position, M[mesh.ParentBone.Index]);
                        triangles.Add(new Vector2(v.X, v.Z));
                    }
                }

                regions[mesh.Name] = triangles;
            }


            //////////////////////////////////////////////
            ////////////////Line Draw Stuff//////////////
            /////////////////////////////////////////////


            lastMouseState = Mouse.GetState();





        }




        #endregion

        #region Update and Draw

        /// <summary>
        /// This function is called to update this component of our game
        /// to the current game time.
        /// </summary>
        /// <param name="gameTime"></param>
        public void Update(GameTime gameTime, BoundingCylinder alienCyl, BoundingCylinder gortCyl, BoundingCylinder dalekCyl) // ii is index
        {

            int viewWidth = game.GraphicsDevice.Viewport.Width;
            int viewHeight = game.GraphicsDevice.Viewport.Height;
            int crossOffset = 1000;

            

            // game.LineDraw.Crosshair(game.PlayerPos + new Vector3(0, -bufferY*.5f+50, bufferX*.5f), 20, Color.White);
            

            crosshairCoordinate = game.Camera.FakeEye + ((game.Camera.FakeCenter - game.Camera.FakeEye) * crossOffset) +
                Vector3.Cross((game.Camera.FakeCenter - game.Camera.FakeEye), new Vector3(0,1,0)) *
                MathHelper.ToRadians((64f * ((float)Mouse.GetState().X / (float)viewWidth) - 32f) * crossOffset) +
                new Vector3(0, 1, 0) * MathHelper.ToRadians((-44f * ((float)Mouse.GetState().Y / (float)viewHeight) + 22f) * crossOffset);
          
            game.LineDraw.Clear();
            game.LineDraw.Begin();
            game.LineDraw.Vertex(game.Camera.Center, Color.White);
            game.LineDraw.Vertex(crosshairCoordinate, Color.Red);
            game.LineDraw.End();
            game.LineDraw.Crosshair(crosshairCoordinate, 20, Color.White);
            Ray mouseRay = new Ray(game.Camera.Center, (crosshairCoordinate-game.Camera.Center));
            if (alienCyl.Intersect(mouseRay)){
                game.HitString = "Alien Selected";
            }
            else if (gortCyl.Intersect(mouseRay)){
                game.HitString = "Gort Selected";
            }
            else if (dalekCyl.Intersect(mouseRay)){
                game.HitString = "Dalek Selected";
            }
            else{
                game.HitString = "None Selected";
            }

            //System.Diagnostics.Trace.WriteLine("alien: " + alienCyl.Intersect(mouseRay));
           // System.Diagnostics.Trace.WriteLine("gort: " + gortCyl.Intersect(mouseRay));
            //System.Diagnostics.Trace.WriteLine("dalek: " + dalekCyl.Intersect(mouseRay));
        }

        /// <summary>
        /// This function is called to draw this game component.
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="gameTime"></param>



        #endregion

    }
}
